/* 
 * Enterprise Library Extensions - DI + ORM.
 * Copyright (C) 2006
 *
 * GNU General Public License
 *
 * This program is free software; you can redistribute 
 * it and/or modify it under the terms of the GNU General Public License 
 * as published by the Free Software Foundation; either version 2 of the 
 * License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful, but 
 * WITHOUT ANY WARRANTY; without even the implied warranty of 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
 * See the GNU General Public License for more details.
 */
using System;
using System.Messaging;
using ELE.Common.Util;
using ELE.EnterpriseLibrary.Common.Logging;
using Microsoft.Practices.EnterpriseLibrary.Logging;

namespace ELE.EnterpriseLibrary.Messaging
{
  /// <summary>
  /// Summary description for MessageSource.
  /// 
  /// Author : Miguel Curi
  /// 
  /// </summary>
  public class MessageSource : LoggingObjectBase
  {
    private MessageSourceInfo myInfo;
    /// <summary>
    /// Initializes a message source that sends messages to a queue defined by the given info
    /// </summary>
    /// <param name="info"></param>
    public MessageSource(MessageSourceInfo info) : this(info, false)
    {
    }
    /// <summary>
    /// Initializes a message sink that listens for messages on a queue defined by the given info 
    /// </summary>
    /// <param name="info">message queue info</param>
    /// <param name="logToContext">should we log errors to the static context ??</param>
    public MessageSource(MessageSourceInfo info, bool logToContext)
    {
      myInfo = info;
    }
    /// <summary>
    /// Sends a message to the queue
    /// </summary>
    /// <param name="objectMessage">the object to place in the body of the message</param>
    public void SendObjectMessage(object objectMessage)
    {
      this.SendObjectMessage(objectMessage, null);
    }
    /// <summary>
    /// Sends and object message and labels it for identification
    /// </summary>
    /// <param name="objectMessage">the object to place in the body of the message</param>
    /// <param name="label">the identification label</param>
    public void SendObjectMessage(object objectMessage, string label)
    {
      
      // Create an instance of MessageQueue. Set its formatter.
      MessageQueue myQueue = null;
      try
      {
        if(myInfo.IsPublicQueue)
        {
          if(MessageQueue.Exists(myInfo.QueueName))
          {
            myQueue = new MessageQueue(myInfo.QueueName);
          }
          else
          {
            myQueue = MessageQueue.Create(myInfo.QueueName);
          }
        }
        else
        {
          myQueue = new MessageQueue(myInfo.QueueName);
        }
        myQueue.Formatter = new BinaryMessageFormatter();
        myQueue.DefaultPropertiesToSend.Recoverable = true;
        if(label != null)
        {
          myQueue.Send(objectMessage, label);
        }
        else if(myInfo.Label != null)
        {
          myQueue.Send(objectMessage, myInfo.Label);
        }
        else
        {
          myQueue.Send(objectMessage);
        }
      }
      catch(Exception e)
      {
        this.LogError("MessageSource: Send object message action failed for queue : " + myInfo.QueueName, e);
        throw e;
      }
      finally
      {
        if(myQueue != null)
        {
          myQueue.Close();
        }
      }
    }
    /// <summary>
    /// Retrieves the source info
    /// </summary>
    public MessageSourceInfo SourceInfo
    {
      get { return myInfo; }
    }
  }
}
